// PairPotentialFunction.h: interface for the PairPotentialFunction class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(PAIR_POTENTIAL_FUNCTION_H)
#define PAIR_POTENTIAL_FUNCTION_H


#include "Function.h"


#include <iostream>
using namespace std;


#include "Time.h" // to check time of cal a set of calculated intensities
                 // relative to additional overhead of cal derivatives
                 // for the purpose of first publication of HMC


class PairPotentialFunction : public Function  
{
public:
	PairPotentialFunction(int i_NInput);
	virtual ~PairPotentialFunction();

	double Value(double *Input);
  double Value(vector<double> &Input);
  double NormValue(double *Input){return 1.0;}
  double NormValue(vector<double> &Input){return 1.0;}

	void BuildDerivative(double *Input, double *Derivative);

  double distanceFromGlobalMinimum(double *solution);

  void print_sol(double *Input, double ChiSq, ofstream& append, string cifLabel = "default")
	{
    printCIF(Input, ChiSq, append, cifLabel);
	}
	void print_sol(double *Input, double ChiSq, char name[]);
  void print_sol(char name[]);
  void printCIF(double *Value, const double ChiSq, ofstream& out, string cifLabel);
	
	void createRandomSol(double *TestInput)
	{
	  int m;

		for(m=1;m<=NInput;m++)	  
    {
		  TestInput[m] = (10.0*ran1())-5.0;
    }
	}

  void test_function();

  void setDeformation(const double& t) { _t = t;}

private:

  /// hold a pair potential coefficient set for a given power of the pair potential
  struct CoefSet
  {
    int n;
    vector<double> a; // coefficients of exp()
    vector<double> b; // exponential coef.
  };
  vector<CoefSet> _allCoef;

  vector<vector<double> > m_atoms;
  int m_nAtom;
  double pairValue(const vector<double>& a1, const vector<double>& a2, int n);
  double derivOfPartOfPairP(const vector<double>& a1, const vector<double>& a2, int n);
  void PairPotentialFunction::updateAtomArray(double *Input);
  int _toPower;  // to which power of the pair potential should we consider?  
  double _t; // deformation parameter
  double _B; // as in (-1)^N*(f-B)^N transformation

	Time timer; // to measure time for first HMC publication
};

#endif // !defined(PAIR_POTENTIAL_FUNCTION_H)
